/**
 * @author Sergey Chikuyonok (sc@design.ru)
 * @copyright Art.Lebedev Studio (http://www.artlebedev.ru)
 */

var userAgent = navigator.userAgent.toLowerCase();

/**
 * Тип и версия браузера пользователя. Взято с jQuery
 */
var browser = {
	version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
	safari: /webkit/.test( userAgent ),
	opera: /opera/.test( userAgent ),
	msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
	mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
};

 /**
 * Возвращает значение CSS-свойства <b>name</b> элемента <b>elem</b>
 * @author John Resig (http://ejohn.org)
 * @param {Element} elem Элемент, у которого нужно получить значение CSS-свойства
 * @param {String} name Название CSS-свойства
 * @return {String}
 */
function getStyle(elem, name) {
	var name_camel = name.replace(/\-(\w)/ig, function(str, p1){return p1.toUpperCase();});
	
	// If the property exists in style[], then it's been set
	// recently (and is current)
	if (elem.style[name_camel]) {
		return elem.style[name_camel];
	}
	//Otherwise, try to use IE's method
	else if (browser.msie) {
		return elem.currentStyle[name_camel];
	}
	// Or the W3C's method, if it exists
	else if (document.defaultView && document.defaultView.getComputedStyle) {
		var s = document.defaultView.getComputedStyle(elem, "");
		return s && s.getPropertyValue(name);
	}
	//Otherwise, we're using some other browser
	else {
		return null;
	}
}


/**
 * Возвращает цвет фона родительского элемента
 * @param {Element} elem Элемент, для которого нужно достать цвет фона
 * 
 * before: 152 calls, 13 ms
 */
function getBgOld(elem) {
	var c;
	do {
		if (elem.nodeType != 1)
			break;
		c = getStyle(elem, 'background-color');
		if (c != 'transparent')
			return c;
	} while (elem = elem.parentNode);
	
	return '#ffffff';
}

var getBg = (function() {
	
	var session_elems = [];
	
	function mainLoop(elem) {
		var c;
		do {
			if (elem.nodeType != 1)
				break;
			
			if (elem.rocon_bg) { // цвет был найден ранее
				return elem.rocon_bg;
			} else { // цвет еще не найден
				session_elems.push(elem);
				c = getStyle(elem, 'background-color');
				if (c != 'transparent')
					return c;
			}
				
		} while (elem = elem.parentNode);
		
		return '#ffffff';
	}
	
	return function(elem){
		session_elems = [];
		var bg = mainLoop(elem);
		// закэшируем цвет фона у всех элементов, по которым проходились
		for (var i = 0; i < session_elems.length; i++) {
			session_elems[i].rocon_bg = bg;
		}
		
		session_elems = null;
		return bg;
	}
})();


window.onload = function() {
	var divs = document.getElementsByTagName('div');
	var bgs = [];
	for (var i = 0; i < divs.length; i++) {
		bgs.push(getBgOld(divs[i]));
	}
	console.log(bgs);
}